module tlb0 (
  input clk,
  input rst,
  // search port 0
  input  [18:0] s0_vpn2,
  input         s0_odd_page,  
  input  [ 7:0] s0_asid,

  output        s0_found,
  output [19:0] s0_pfn,
  output [ 2:0] s0_c,
  output        s0_d,
  output        s0_v,

  // write port
  input         we,
  input  [18:0] w_vpn2,
  input  [ 7:0] w_asid,
  input         w_g,
  input  [19:0] w_pfn0,
  input  [ 2:0] w_c0,
  input         w_d0,
  input         w_v0,
  input  [19:0] w_pfn1,
  input  [ 2:0] w_c1,
  input         w_d1,
  input         w_v1
);

  reg [ 18:0] tlb_vpn2;
  reg [  7:0] tlb_asid;
  reg         tlb_g   ;
  reg [ 19:0] tlb_pfn0;
  reg [  2:0] tlb_c0  ;
  reg         tlb_d0  ;
  reg         tlb_v0  ;
  reg [ 19:0] tlb_pfn1;
  reg [  2:0] tlb_c1  ;
  reg         tlb_d1  ;
  reg         tlb_v1  ;

  wire match0;
  assign match0 = (s0_vpn2 == tlb_vpn2)
    && ((s0_asid == tlb_asid) || tlb_g);

  // search port0
  assign s0_found = match0;
  assign s0_pfn   = s0_odd_page ? tlb_pfn1 : tlb_pfn0;
  assign s0_c     = s0_odd_page ? tlb_c1   : tlb_c0  ;
  assign s0_d     = s0_odd_page ? tlb_d1   : tlb_d0  ;
  assign s0_v     = s0_odd_page ? tlb_v1   : tlb_v0  ;

  // write
  always @(posedge clk) begin
    if (rst) begin
      tlb_vpn2 <= 0;
      tlb_asid <= 0;
      tlb_g    <= 0;

      tlb_pfn0 <= 0;
      tlb_c0   <= 0;
      tlb_d0   <= 0;
      
      tlb_pfn1 <= 0;
      tlb_c1   <= 0;
      tlb_d1   <= 0;

      tlb_v0 <= 1'b0;
      tlb_v1 <= 1'b0;
    end else if (we) begin
      tlb_vpn2 <= w_vpn2;
      tlb_asid <= w_asid;
      tlb_g    <= w_g;

      tlb_pfn0 <= w_pfn0;
      tlb_c0   <= w_c0;
      tlb_d0   <= w_d0;
      
      tlb_pfn1 <= w_pfn1;
      tlb_c1   <= w_c1;
      tlb_d1   <= w_d1;

      tlb_v0 <= w_v0;
      tlb_v1 <= w_v1;
    end
  end

endmodule